﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using Microsoft.DirectX.DirectInput;

namespace DirectXSim
{
    public enum CollisionType
    {
        None,
        Barrier,
        Obstacle,
        Opponent,
        EndTrack,
        Pickup
    }
    

    public partial class RenderWindow : Form
    {
        
        private TimeSpan lightChange = new TimeSpan(0, 0, 5);
        private DateTime lightChangeTime;

        private Microsoft.DirectX.Direct3D.Device _device;
        private Microsoft.DirectX.DirectInput.Device keyb;
       
        //Skybox
        private Mesh skyboxmesh;
        private Material[] skyboxmaterials;
        private Texture[] skyboxtextures;

        private Texture scenerytexture;
        private Material material;

        //Sprite for text
        private Microsoft.DirectX.Direct3D.Font text;

        private Game _theGame;
        private Camera _camera;
        
        public RenderWindow()
        {
            InitializeComponent();
            this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);

            _theGame = new Game(12);

            _theGame.AddCar(4.5f,3.5f,0.0f); //Player
            _theGame.AddCar(4.0f,3.5f,0.0f); //Opponent


        }

        public void InitializeFont()
        {
            System.Drawing.Font systemfont = new System.Drawing.Font("Arial", 12f, FontStyle.Regular);
            text = new Microsoft.DirectX.Direct3D.Font(_device, systemfont);
        }


        public void InitializeDevice()
        {
            PresentParameters presentParams = new PresentParameters();
            presentParams.Windowed = true;
            presentParams.SwapEffect = SwapEffect.Discard;
            presentParams.AutoDepthStencilFormat = DepthFormat.D16;
            presentParams.EnableAutoDepthStencil = true;
            presentParams.BackBufferWidth = 800;
            presentParams.BackBufferHeight = 600;

            _device = new Microsoft.DirectX.Direct3D.Device(0, Microsoft.DirectX.Direct3D.DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, presentParams);

            _device.RenderState.Lighting = true;// true;
            
            //General directional light behind car..
            _device.Lights[0].Type = LightType.Directional;
            _device.Lights[0].Diffuse = Color.White;
            _device.Lights[0].Range = 150.0f;
            //Point downwards
            _device.Lights[0].Direction = new Vector3(-2.7f, -0.1f, 1.0f);           
            _device.Lights[0].Update();
            _device.Lights[0].Enabled = true;

            //Car headlight
            _device.Lights[1].Type = LightType.Spot;
            _device.Lights[1].Diffuse = Color.White;
            _device.Lights[1].Ambient = Color.Blue;
            _device.Lights[1].Position = new Vector3(_theGame.MyCar.Position.X, _theGame.MyCar.Position.Y, _theGame.MyCar.Position.Z);
            //Look forwards on y axis
            _device.Lights[1].Direction = new Vector3(0, 1, 0);
            _device.Lights[1].Range = 5.0f;
            _device.Lights[1].Attenuation0 = 1.0f;
            _device.Lights[1].Falloff = 1.0f;
            _device.Lights[1].InnerConeAngle = 0.5f;
            _device.Lights[1].OuterConeAngle = 1.0f;
            _device.Lights[1].Update();
            _device.Lights[1].Enabled = true;

            //Point light above car
            _device.Lights[2].Type = LightType.Point;
            _device.Lights[2].Diffuse = Color.Red;
            _device.Lights[2].Ambient = Color.Red;
            _device.Lights[2].Position = new Vector3(_theGame.MyCar.Position.X, _theGame.MyCar.Position.Y, _theGame.MyCar.Position.Z + 1);
            _device.Lights[2].Range = 3.0f;
            _device.Lights[2].Attenuation0 = 5.0f;
            _device.Lights[2].Update();
            _device.Lights[2].Enabled = true;


            _device.SamplerState[0].MinFilter = TextureFilter.Anisotropic;
            _device.SamplerState[0].MagFilter = TextureFilter.Anisotropic;
            _device.SamplerState[0].AddressU = TextureAddress.Mirror;
            _device.SamplerState[0].AddressV = TextureAddress.Mirror;

            _camera = new Camera();

            _theGame.LoadTrack(ref _device);


            //_device.RenderState.PointSpriteEnable = true;
            //_device.RenderState.PointScaleEnable = true;

            //_theGame.MyCar.Position = new Vector3(carStartX, carStartY, carStartZ);
            //opponentMeshPosition = new Vector3(opponentStartX, opponentStartY, opponentStartZ);
            //itemMeshPosition = new Vector3(5.0f, 10.0f, 0.5f);

        }

        public void SetupData()
        {
            _theGame.Start();
            lightChangeTime = DateTime.Now;
        }

        public void InitializeInputDevices()
        {
            keyb = new Microsoft.DirectX.DirectInput.Device(SystemGuid.Keyboard);
            keyb.SetCooperativeLevel(this, CooperativeLevelFlags.Background | CooperativeLevelFlags.NonExclusive);
            keyb.Acquire();
        }

        private void    ReadUserInput()
        {
            KeyboardState keys = keyb.GetCurrentKeyboardState();

            if (keys[Key.Right])
            {
                _theGame.MyCar.TurnRight();
            }
            if (keys[Key.Left])
            {
                _theGame.MyCar.TurnLeft();
             }
            if (keys[Key.Down])
            {
                _theGame.MyCar.Brake();
            }
            if (keys[Key.Space])
            {
                _theGame.MyCar.HandBrake();
            }
            if (keys[Key.Up])
            {
                _theGame.MyCar.Accelerate();
            }
            //Modify camera position
            if (keys[Key.Insert])
            {
                _camera.CamX += 0.05f;
            }
            if (keys[Key.Delete])
            {
                _camera.CamX -= 0.05f;
            }
            if (keys[Key.Home])
            {
                _camera.CamY += 0.05f;
            }
            if (keys[Key.End])
            {
                _camera.CamY -= 0.05f;
            }
            if (keys[Key.PageUp])
            {
                _camera.CamZ += 0.05f;
            }
            if (keys[Key.PageDown])
            {
                _camera.CamZ -= 0.05f;
            }
            //Modify Camera Target
            //if (keys[Key.Q])
            //{
            //    targetx += 0.05f;
            //}
            //if (keys[Key.A])
            //{
            //    targetx -= 0.05f;
            //}
            //if (keys[Key.W])
            //{
            //    targety += 0.05f;
            //}
            //if (keys[Key.S])
            //{
            //    targety -= 0.05f;
            //}
            //if (keys[Key.E])
            //{
            //    targetz += 0.05f;
            //}
            //if (keys[Key.D])
            //{
            //    targetz -= 0.05f;
            //}
            //Reset Camera Position and Target
            if (keys[Key.R])
            {
                _camera.Reset();
            }
            if (keys[Key.T])
            {
                _camera.FarView();

            }
            if (keys[Key.Y])
            {
                _camera.NearView();

            }

        }

        protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
        {

            if (_theGame.Finished == true)
            {
                GameFinished();
                this.Invalidate();
            }
            else if (_theGame.Initializing == true)
            {
                SpinCamInit();
            }
            else
            {
                
                ReadUserInput();

                //Reposition camera
                _camera.Update(ref _device);

                //Calculate world position
                _theGame.MyCar.UpdatePosition(true);
                _theGame.OpponentCar.UpdatePosition(false);

                _theGame.CheckCarPositions();
                _theGame.CheckCollisions();

                _device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.DarkSlateBlue, 1.0f, 0);
                _device.BeginScene();

                //Draw the track
                //Rotate the track around the car
                _device.Transform.World = Matrix.Translation(-(float)_theGame.MyCar.Position.X, -(float)_theGame.MyCar.Position.Y, -(float)_theGame.MyCar.Position.Z);
                _device.VertexFormat = CustomVertex.PositionNormalTextured.Format;
                //Change texture map               
                _device.SetTexture(0, scenerytexture);
                //_device.RenderState.Ambient = Color.LightPink;
                _device.DrawUserPrimitives(PrimitiveType.TriangleList, _theGame.Track.PrimitiveCount, _theGame.Track.VerticesArray);

                //Draw the car
                _device.RenderState.Ambient = Color.WhiteSmoke;
                _device.Transform.World = Matrix.Scaling(_theGame.MyCar.Scaling, _theGame.MyCar.Scaling, _theGame.MyCar.Scaling) * Matrix.RotationYawPitchRoll((float)Math.PI / 2, _theGame.MyCar.Angle - 29.85f, (float)Math.PI / 2);
                _theGame.MyCar.Draw(ref _device);


                //Draw opponent car(s)
                //Translate around our car, rotate so its the right way up
                _device.Transform.World = Matrix.Scaling(_theGame.OpponentCar.Scaling, _theGame.OpponentCar.Scaling, _theGame.OpponentCar.Scaling)
                    * Matrix.RotationX((float)Math.PI / 2)
                    * Matrix.Translation(_theGame.OpponentCar.Position.X - _theGame.MyCar.Position.X,
                                         _theGame.OpponentCar.Position.Y - _theGame.MyCar.Position.Y,
                                         _theGame.OpponentCar.Position.Z - _theGame.MyCar.Position.Z);
                _theGame.OpponentCar.Draw(ref _device);

                //Draw pickup items
                DrawItems();

                //Draw skybox
                _device.RenderState.Ambient = Color.White;
                _device.Transform.World = Matrix.Scaling(5.0f,5.0f,5.0f) * Matrix.RotationX((float)Math.PI / 2);
                DrawMesh(skyboxmesh, skyboxmaterials, skyboxtextures);

                UpdateLights();

                DrawInfo();
                  
                _device.EndScene();
                _device.Present();
                this.Invalidate();
            }
        }

        private void DrawItems()
        {
            _device.SetTexture(0, null);
            foreach (BonusItem currentItem in _theGame.Track.BonusItemList)
            {
                _device.Material = currentItem.Material;

                _device.Transform.World = Matrix.Scaling(currentItem.Radius, currentItem.Radius, currentItem.Radius) *
                    Matrix.RotationX((float)Math.PI / 2)
                    * Matrix.Translation(currentItem.Position.X - _theGame.MyCar.Position.X,
                    currentItem.Position.Y - _theGame.MyCar.Position.Y,
                    currentItem.Position.Z - _theGame.MyCar.Position.Z);
                currentItem.ItemMesh.DrawSubset(0);
            }
        }

        private void SpinCamInit()
        {
            double CamPosDX;
            double CamPosDZ;
            float CamPosFloatX;
            float CamPosFloatZ;

            //was 1.5 to 3.5
            for (double d = Math.PI * 0.5; d < Math.PI * 2.5; d = d + 0.01)
            {

                CamPosDX = Math.Cos(d);
                CamPosDZ = Math.Sin(d);
                CamPosFloatX = float.Parse(CamPosDX.ToString());
                CamPosFloatZ = float.Parse(CamPosDZ.ToString());

                _device.Transform.View = Matrix.LookAtLH(new Vector3(CamPosFloatX, CamPosFloatZ, 0.6f), new Vector3(0, 0, 0), new Vector3(0, 0, 1));

                _device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.DarkSlateBlue, 1.0f, 0);
                _device.BeginScene();

                //Draw the track
                //Rotate the track around the car
                _device.Transform.World = Matrix.Translation(-(float)_theGame.MyCar.Position.X, -(float)_theGame.MyCar.Position.Y, -(float)_theGame.MyCar.Position.Z);

                _device.VertexFormat = CustomVertex.PositionNormalTextured.Format;
                _device.SetTexture(0, scenerytexture);
                _device.RenderState.Ambient = Color.DarkGray;
                _device.DrawUserPrimitives(PrimitiveType.TriangleList, _theGame.Track.PrimitiveCount, _theGame.Track.VerticesArray);

                //Draw the car
                _device.Transform.World = Matrix.Scaling(_theGame.MyCar.Scaling, _theGame.MyCar.Scaling, _theGame.MyCar.Scaling) * Matrix.RotationYawPitchRoll((float)Math.PI / 2, _theGame.MyCar.Angle - 29.85f, (float)Math.PI / 2);
                _theGame.MyCar.Draw(ref _device);
//                DrawMesh(carMesh, carMeshMaterials, carMeshTextures);
                //_theGame.OpponentCar.Draw(ref _device);

                //DrawMesh(opponentMesh, opponentMeshMaterials, opponentMeshTextures);

                //Draw skybox
                //_device.RenderState.Ambient = Color.White;
                //_device.Transform.World = Matrix.RotationX((float)Math.PI / 2);
                //DrawMesh(skyboxmesh, skyboxmaterials, skyboxtextures);

                DrawInfo();

                //DrawProgress();

                _device.EndScene();
                _device.Present();
                this.Invalidate();

                //Accelerate starts the race, even if spin not completed
                KeyboardState keys = keyb.GetCurrentKeyboardState();
                if (keys[Key.Up]) break;
            }
            _theGame.Initializing = false;
            SetupData();

        }

        /// <summary>
        /// Memory usage of this function needs investigating - adds 8MB every second or so.
        /// </summary>
        private void DrawProgress()
        {
            Vector2[] vertList = new Vector2[2];
            vertList[0].X = 300;
            vertList[0].Y = 10;
            vertList[1].X = 300 + (int)_theGame.MyCar.Position.Y;
            vertList[1].Y = 10;

            Microsoft.DirectX.Direct3D.Line progressLine = new Line(_device);
            progressLine.Width = 10.0f;            
            progressLine.Begin();
            progressLine.Draw(vertList, Color.Red);
            progressLine.End();

            Vector2[] vertList2 = new Vector2[2];
            vertList2[0].X = 300 + (int)_theGame.MyCar.Position.Y;
            vertList2[0].Y = 10;
            vertList2[1].X = 300 + _theGame.Track.Height;
            vertList2[1].Y = 10;

            Microsoft.DirectX.Direct3D.Line progressLine2 = new Line(_device);
            progressLine2.Width = 10.0f;
            progressLine2.Begin();
            progressLine2.Draw(vertList2, Color.Green);
            progressLine2.End();
        }

        private void GameFinished()
        {
            //Make this 3D Text!
            //gamespeed = 0.0f;
            _device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Black, 1.0f, 0);
            _device.BeginScene();
            text.DrawText(null, "Game Over", new Point(380, 280), Color.White);
            text.DrawText(null, string.Format("Final Position {0}", _theGame.MyCar.RacePosition), new Point(380, 300), Color.White);
            text.DrawText(null, string.Format("Best Lap Time {0}", _theGame.MyCar.BestLapTime), new Point(380, 320), Color.White);
            _device.EndScene();
            _device.Present();

            //finished = true;
        }

        private void DrawInfo()
        {
            text.DrawText(null, "Total Time", new Point(30, 20), Color.Yellow);
            text.DrawText(null, string.Format("{0}'{1}''{2}", _theGame.TotalTime.Minutes, _theGame.TotalTime.Seconds, _theGame.TotalTime.Milliseconds), new Point(30, 34), Color.White);
            text.DrawText(null, "Lap Time", new Point(30, 48), Color.Orange);
            text.DrawText(null, string.Format("{0}'{1}''{2}", _theGame.LapTime.Minutes, _theGame.LapTime.Seconds, _theGame.LapTime.Milliseconds), new Point(30, 62), Color.White);
            text.DrawText(null, "Best Lap Time", new Point(30, 76), Color.Red);
            text.DrawText(null, string.Format("{0}'{1}''{2}", _theGame.MyCar.BestLapTime.Minutes, _theGame.MyCar.BestLapTime.Seconds, _theGame.MyCar.BestLapTime.Milliseconds), new Point(30, 90), Color.White);

            text.DrawText(null, "Position", new Point(700, 20), Color.Yellow);
            text.DrawText(null, string.Format("{0}/{1}",_theGame.MyCar.RacePosition,_theGame.TotalRacers), new Point(700, 34), Color.White);

            text.DrawText(null, "Lap", new Point(700, 48), Color.Red);
            text.DrawText(null, string.Format("{0}/{1}", _theGame.MyCar.LapNumber, _theGame.TotalLaps), new Point(700, 62), Color.White);

            text.DrawText(null, string.Format("{0}mph", _theGame.MyCar.SpeedMph.ToString()), new Point(700, 550), Color.White);
            text.DrawText(null, string.Format("{0}kph", _theGame.MyCar.SpeedKph.ToString()), new Point(700, 564), Color.White);

            //text.DrawText(null, "Opponent Position Data", new Point(30, 350), Color.Red);
            //text.DrawText(null, string.Format("X: {0} Y: {1} Z: {2}", opponentMeshPosition.X, opponentMeshPosition.Y, opponentMeshPosition.Z), new Point(30, 364), Color.White);


            //text.DrawText(null, "Camera Data", new Point(30, 150), Color.Red);
            //text.DrawText(null, string.Format("X: {0} Y: {1} Z: {2} Angle: {3}", camx, camy, camz, _theGame.MyCar.Angle), new Point(30, 164), Color.White);

            //text.DrawText(null, "Light Data", new Point(30, 150), Color.Red);
            //text.DrawText(null, string.Format("X: {0} Y: {1} Z: {2}", _device.Lights[0].XDirection, _device.Lights[0].YDirection, _device.Lights[0].ZDirection), new Point(30, 164), Color.White);


            text.DrawText(null, "Car Position", new Point(30, 550), Color.Red);
            text.DrawText(null, string.Format("X: {0} Y: {1} Z: {2} Angle: {3} Speed: {4}", _theGame.MyCar.Position.X, _theGame.MyCar.Position.Y, _theGame.MyCar.Position.Z, _theGame.MyCar.Angle, _theGame.MyCar.GameSpeed), new Point(30, 564), Color.White);


        }

        public void SetUpCamera()
        {
            _device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI / 4, (float)this.Width / (float)this.Height, 0.1f, 200f);

            //Camera Position, Camaera Target
            _device.Transform.View = Matrix.LookAtLH(_camera.CameraVector, _camera.TargetVector, new Vector3(0, 0, 1));
        }

        //public void UpdateCamera()
        //{
        //    _device.Transform.View = Matrix.LookAtLH(new Vector3(camx, camy, camz), new Vector3(targetx, targety, targetz), new Vector3(0, 0, 1));
        //}

        //private void UpdatePosition(ref Vector3 position)
        //{
        //    position.Y += (float)Math.Cos(_theGame.MyCar.Angle) * gamespeed;
        //    position.X += (float)Math.Sin(_theGame.MyCar.Angle) * (gamespeed / 4);           
        //}

        private void UpdateLights()
        {
            //Update light above car every 5 seconds
            if ((DateTime.Now - lightChangeTime) >= lightChange)
            {
                Random random = new Random();
                _device.Lights[1].Diffuse = Color.FromArgb(random.Next(255), random.Next(255), random.Next(255));
                _device.Lights[1].Update();
                
                if (_device.Lights[2].Diffuse == Color.Red)
                {
                    _device.Lights[2].Diffuse = Color.Blue;
                    _device.Lights[2].Ambient = Color.Blue;
                }
                else
                {
                    _device.Lights[2].Diffuse = Color.Red;
                    _device.Lights[2].Ambient = Color.Red;
                }
                lightChangeTime = DateTime.Now;
                _device.Lights[2].Update();
            }

        }

        //private CollisionType CheckCollision(Vector3 position, float radius)
        //{
        //    if (noCollisionMode == false)
        //    {
        //        //Check against barrier of track
        //        if ((position.X < 1) || (position.X > WIDTH - 1))
        //        {
        //            return CollisionType.Barrier;
        //        }

        //        //Check if reached end of track
        //        if ((position.Y <= -1) || (position.Y > HEIGHT))
        //        {
        //            return CollisionType.EndTrack;
        //        }

        //        //Check against obstacles
        //        if (raceTrack[(int)position.X, (int)position.Y] > 0)
        //        {
        //            return CollisionType.Obstacle;
        //        }

        //        //Check if hit opponent car(s)
        //        if (Math.Sqrt(Math.Pow(opponentMeshPosition.X - _theGame.MyCar.Position.X, 2) + Math.Pow(opponentMeshPosition.Y - _theGame.MyCar.Position.Y, 2) + Math.Pow(opponentMeshPosition.Z - _theGame.MyCar.Position.Z, 2)) < carMeshRadius + opponentMeshRadius)
        //        {
        //            return CollisionType.Opponent;
        //        }
        //    }

        //        //Check if we are on a pick-up
        //        for (int i = 0; i < itemList.Count; i++)
        //        {
        //            itemStruct currentItem = (itemStruct)itemList[i];
        //            if (Math.Sqrt(Math.Pow(currentItem.position.X - position.X, 2) + Math.Pow(currentItem.position.Y - position.Y, 2) + Math.Pow(currentItem.position.Z - position.Z, 2)) < radius + currentItem.radius)
        //            {
        //                //Remove from list of pickups
        //                itemList.RemoveAt(i);
        //                i--;
        //                switch (currentItem.type)
        //                {
        //                    case ItemType.Boost:
        //                        noCollisionMode = false;
        //                        gamespeed += 0.2f;
        //                        break;
        //                    case ItemType.NoCollision:
        //                        noCollisionMode = true;
        //                        break;
        //                    case ItemType.Slippery:
        //                        noCollisionMode = false;
        //                        _theGame.MyCar.Angle += (float)Math.PI / 2;
        //                        break;
        //                    case ItemType.Stop:
        //                        noCollisionMode = false;
        //                        gamespeed = 0.0f;
        //                        break;
        //                    default:
        //                        noCollisionMode = false;
        //                        gamespeed = 0.0f;
        //                        break;
        //                }


        //                return CollisionType.Pickup;
        //            }
        //        }
            


        //    return CollisionType.None;
        //}

        //private CollisionType CheckOpponentCollision()
        //{

        //    //Check against barrier of track
        //    if ((opponentMeshPosition.X < 1) || (opponentMeshPosition.X > WIDTH - 1))
        //    {
        //        return CollisionType.Barrier;
        //    }

        //    //Check if reached end of track
        //    if ((opponentMeshPosition.Y <= -1) || (opponentMeshPosition.Y > HEIGHT))
        //    {
        //        return CollisionType.EndTrack;
        //    }

        //    //Check against obstacles
        //    if (raceTrack[(int)opponentMeshPosition.X, (int)opponentMeshPosition.Y] > 0)
        //    {
        //        return CollisionType.Obstacle;
        //    }

        //    //Check if hit opponent car(s)
        //    if (Math.Sqrt(Math.Pow(opponentMeshPosition.X - _theGame.MyCar.Position.X, 2) + Math.Pow(opponentMeshPosition.Y - _theGame.MyCar.Position.Y, 2) + Math.Pow(opponentMeshPosition.Z - _theGame.MyCar.Position.Z, 2)) < carMeshRadius + opponentMeshRadius)
        //    {
        //        return CollisionType.Opponent;
        //    }

        //    return CollisionType.None;
        //}

        public void LoadMeshes()
        {
                        
            //LoadMesh("car.x", ref carMesh, ref carMeshMaterials, ref carMeshTextures, ref carMeshRadius);
            //LoadMesh("car.x", ref opponentMesh, ref opponentMeshMaterials, ref opponentMeshTextures, ref opponentMeshRadius);
            
            _theGame.MyCar.LoadMesh("car.x", ref _device);
            _theGame.OpponentCar.LoadMesh("car.x", ref _device);

            float dummy = 0;
            LoadMesh("skybox2.x", ref skyboxmesh, ref skyboxmaterials, ref skyboxtextures, ref dummy);



        }


        public void LoadTexturesAndMaterials()
        {
            material = new Material();

            material.Diffuse = Color.White;
            material.Specular = Color.White;
            material.SpecularSharpness = 15.0F;

            scenerytexture = TextureLoader.FromFile(_device, "texturemap.jpg");
            //scenerytexture2 = TextureLoader.FromFile(_device, "texturemap2.jpg");

        }

        private void LoadMesh(string filename, ref Mesh mesh, ref Material[] meshmaterials, ref Texture[] meshtextures, ref float meshradius)
        {
            ExtendedMaterial[] materialarray;
            mesh = Mesh.FromFile(filename, MeshFlags.Managed, _device, out materialarray);
            if ((materialarray != null) && (materialarray.Length > 0))
            {
                meshmaterials = new Material[materialarray.Length];
                meshtextures = new Texture[materialarray.Length];

                for (int i = 0; i < materialarray.Length; i++)
                {
                    meshmaterials[i] = materialarray[i].Material3D;
                    meshmaterials[i].Ambient = meshmaterials[i].Diffuse;

                    if ((materialarray[i].TextureFilename != null) && (materialarray[i].TextureFilename != string.Empty))
                    {
                        meshtextures[i] = TextureLoader.FromFile(_device, materialarray[i].TextureFilename);
                    }
                }
            }
            mesh = mesh.Clone(mesh.Options.Value, CustomVertex.PositionNormalTextured.Format, _device);
            mesh.ComputeNormals();

            VertexBuffer vertices = mesh.VertexBuffer;
            GraphicsStream stream = vertices.Lock(0, 0, LockFlags.None);
            Vector3 meshcenter;
            meshradius = Geometry.ComputeBoundingSphere(stream, mesh.NumberVertices, mesh.VertexFormat, out meshcenter) * 0.08f;
            vertices.Unlock();
        }

        public void DrawMesh(Mesh mesh, Material[] meshmaterials, Texture[] meshtextures)
        {
            for (int i = 0; i < meshmaterials.Length; i++)
            {
                _device.Material = meshmaterials[i];
                _device.SetTexture(0, meshtextures[i]);
                mesh.DrawSubset(i);
            }
        }

        //public void LoadFloorplan()
        //{

        //    WIDTH = 10;
        //    HEIGHT = 250;

        //    raceTrack = new int[WIDTH, HEIGHT];

        //    Random random = new Random();

        //    //Create obstacles - one at each row, at a random column
        //    for (int y = 10; y < HEIGHT; y++)
        //    {
        //        //Barriers at both sides of track
        //        raceTrack[0, y] = 1;
        //        raceTrack[WIDTH - 1, y] = 1;

        //        if (y % 5 == 0)
        //        {
        //            //Random Obstacle
        //            int x = random.Next(WIDTH - 2) + 1;

        //            raceTrack[x, y] = random.Next(3) + 2;
        //        }
        //    }
        //}

    }
}
